from sanic import Blueprint
from sanic import response, request
import hashlib
import html
from urllib import parse
from functools import reduce
import re
import json
import os

# from selenium import webdriver

SEV_DOWN_PATH = '/root/Download'

api = Blueprint('my_api_v1', url_prefix='/api')


# chrome_options = webdriver.ChromeOptions()
# chrome_options.add_argument('--headless')
# chrome_options.add_argument('--no-sandbox')
# chrome_options.add_argument('--disable-gpu')
# driver = webdriver.Chrome(chrome_options=chrome_options)
# driver.get("file:///root/sanic/resource/runHTML.html")


@api.route("/hash", methods=['POST'])
async def hashEncrypt(request):
    try:
        dic = request.json
    except Exception:
        return response.html('<h2>need json request</h2>')
    # print(dic)
    if dic['crypt'] == 'encrypt':
        orginT = dic['originText']
        m = None
        if dic['cryptType'] == 'MD5':
            m = hashlib.md5()
        elif dic['cryptType'] == 'SHA1':
            m = hashlib.sha1()
        elif dic['cryptType'] == 'SHA256':
            m = hashlib.sha256()
        else:
            return response.html('<h2>error cryptType</h2>')
        m.update(orginT.encode("utf-8"))  # 参数必须是byte类型，否则报Unicode-objects must be encoded before hashing错误
        md5value = m.hexdigest()
        print(dic['cryptType'] + ' : ' + md5value)
        return response.json(
            {'originText': dic['originText'], 'encryptedText': md5value, 'cryptType': dic['cryptType']})
    else:
        return response.html('<h2>error hash can not decrypt</h2>')


@api.route("/ncr", methods=['POST'])
async def codeConvertNCR(request):
    try:
        dic = request.json
    except Exception:
        return response.html('<h2>need json request</h2>')
    # print(dic)
    inputStr = dic['inputStr'] and dic['inputStr'] or ''
    if dic['type'] == 'toCN':
        out = html.unescape(inputStr)
        return response.json({'inputStr': inputStr, 'outputStr': out})
    elif dic['type'] == 'toNCR':
        out = html.escape(inputStr)
        temp = ''
        for i in range(0, len(inputStr)):
            if out[i] == inputStr[i]:
                temp += '&#x%04x;' % (ord(inputStr[i]))
            else:
                temp += out[i]
        out = temp
        return response.json({'inputStr': inputStr, 'outputStr': out})
    else:
        return response.html('<h2>error, type not support</h2>')


@api.route("/unicode", methods=['POST'])
async def codeConvertUnicode(request):
    try:
        dic = request.json
    except Exception:
        return response.html('<h2>need json request</h2>')
    # print(dic)
    str = dic['inputStr'] and dic['inputStr'] or ''
    if dic['type'] == 'UtoCN':
        rex = re.compile(r'\\[u|U](\w{4})')

        def func(m):
            try:
                return '%c' % int(m.group(1), 16)
            except Exception as e:
                return m.group(1)

        out = rex.sub(func, str)
        return response.json({'outputStr': out, 'inputStr': str})
    elif dic['type'] == 'CNtoU':
        strArr = map(lambda x: '\\u%04x' % (ord(x)), str)
        out = reduce(lambda x, y: x + y, strArr)
        return response.json({'outputStr': out, 'inputStr': str})
    else:
        return response.html('<h2>error, type not support</h2>')


@api.route("/urlcode", methods=['POST'])
async def codeConvertUrlcode(request):
    try:
        dic = request.json
    except Exception:
        return response.html('<h2>need json request</h2>')
    # print(dic)
    str = dic['inputStr'] and dic['inputStr'] or ''
    if dic['type'] == 'encode':
        out = parse.quote(str)
        return response.json({'outputStr': out, 'inputStr': str})
    elif dic['type'] == 'decode':
        out = parse.unquote(str)
        return response.json({'outputStr': out, 'inputStr': str})
    else:
        return response.html('<h2>error, type not support</h2>')


@api.route("/wechatVerify", methods=['GET'])
async def wechatVerify(request):
    try:
        dic = request.args
        signature = dic['signature'][0]
        timestamp = dic['timestamp'][0]
        nonce = dic['nonce'][0]
        echostr = dic['echostr'][0]
        token = 'qsfG131977Da'
    except Exception:
        return response.text('wrong')
    arr = [timestamp, nonce, token]
    arr.sort()
    sortedStr = "".join(arr)
    m = hashlib.sha1()
    m.update(sortedStr.encode("utf-8"))
    sha1value = m.hexdigest()
    if sha1value == signature:
        return response.text(echostr)
    else:
        return response.text("wrong")


# @api.route("/getBusline", methods=['GET'])
# async def getBusline(request):
#     try:
#         dic = request.args
#         city = dic['city'][0]
#         num = dic['num'][0]
#     except Exception:
#         return response.text('wrong')
#
#     js = 'done = arguments[0];search_Py_async("' + city + '", "' + num + '");'
#     result = driver.execute_async_script(js)
#     decode_json = json.loads(result)
#
#     return response.json(decode_json)


@api.route("/downlink", methods=['POST'])
async def linkDownload(request):
    try:
        dic = request.json
    except Exception:
        return response.html('<h2>need json request</h2>')
    # print(dic)
    password = dic['pass'] and dic['pass'] or ''
    link = dic['link'] and dic['link'] or ''
    if link == '':
        return response.html('error, invaild link')
    elif password != 'niraya.top.zhou':
        return response.html('error, pass incorrect')
    else:
        # 下载文件
        os.system('wget %s -P %s' % (link, SEV_DOWN_PATH))
        return response.json({'result': 'ok'})


@api.route("/getServerfilelist", methods=['GET'])
async def getServerfilelist(request):
    file_name = os.listdir(SEV_DOWN_PATH)
    return response.json({'filelist': file_name})


@api.route("/getfile", methods=['GET'])
async def getfile(request):
    try:
        dic = request.args
        file_name = dic['file'][0]
        password = dic['pass'][0]
    except Exception:
        return response.html('<h2>error, request params error</h2>')

    if password != 'niraya.top.zhou':
        return response.html('error, pass incorrect')

    file_path = SEV_DOWN_PATH + '/' + file_name
    print(file_path)
    headers = {
        "Content-Type": 'application/octet-stream',
        'X-Content-Type-Options': 'nosniff',
        'X-Accel-Redirect': '/download_temp_file/' + file_name,
    }
    return await response.file_stream(file_path, headers=headers, filename=file_name)


@api.route("/deletefile", methods=['GET'])
async def deletefile(request):
    try:
        dic = request.args
        file_name = dic['file'][0]
        password = dic['pass'][0]
    except Exception:
        return response.html('<h2>need json request</h2>')

    if password != 'niraya.top.zhou':
        return response.html('error, pass incorrect')

    file_path = SEV_DOWN_PATH + '/' + file_name
    print(file_path)
    os.system('rm %s' % file_path)
    return response.json({'result': 'ok'})
